package com.snakerflow.framework.ws.web;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.HistoryTask;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.WorkItem;
import org.snaker.engine.model.EndModel;
import org.snaker.engine.model.NodeModel;
import org.snaker.engine.model.ProcessModel;
import org.snaker.engine.model.TaskModel.TaskType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.snakerflow.framework.flow.dao.ApprovalDao;
import com.snakerflow.framework.flow.service.SnakerEngineFacets;
import com.snakerflow.framework.security.shiro.ShiroUtils;
import com.snakerflow.framework.ws.Constant;
import com.snakerflow.framework.ws.vo.WsCommonResponse;

/**
 * Snaker流程引擎任务相关Controller
 * @author 何东
 * @since 0.1
 */
@Controller
@RequestMapping(value = "/ws/snaker/task")
public class WsTaskController {
	
	private static final Logger log = LoggerFactory.getLogger(WsTaskController.class);
	/** 操作员 状态（正常） */
	private static final String OPERATOR_STATUS = "running";
	
	@Autowired
	ApprovalDao approvalDao;
	
	@Autowired
	private SnakerEngineFacets facets;
	
	/**
	 * 根据用户名或角色分页查询待办列表
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "activeTasks", method=RequestMethod.GET)
	public WsCommonResponse<WorkItem> activeTasks(HttpServletRequest request) {
		WsCommonResponse<WorkItem> wsResp = new WsCommonResponse<WorkItem>();
		
		int pageSize = 0;
		if (StringUtils.isNotBlank(request.getParameter(Constant.PARA_PAGE_SIZE))) {
			pageSize = Integer.valueOf(request.getParameter(Constant.PARA_PAGE_SIZE));
		}
		
		Page<WorkItem> majorPage = null;
		if (pageSize > 0) {
			majorPage = new Page<WorkItem>(pageSize);
		} else {
			majorPage = new Page<WorkItem>();
		}
		
		int currPage = 1;
		if (pageSize > 0 && StringUtils.isNotBlank(request.getParameter(Constant.PARA_START_IDX))) {
			currPage = Integer.valueOf(request.getParameter(Constant.PARA_START_IDX)) / pageSize + 1;
		}
		
		majorPage.setPageNo(currPage);
		
		/*
		List<String> list = ShiroUtils.getGroups();
		list.add(ShiroUtils.getUsername());
		log.info(list.toString());
		String[] assignees = new String[list.size()];
		list.toArray(assignees);
		*/
		List<String> list = new ArrayList<String>();
		if (StringUtils.isNotBlank(request.getParameter(Constant.PARA_USERNAME))) {
			list.add(request.getParameter(Constant.PARA_USERNAME));
			list.addAll(ensureGroup(request.getParameter(Constant.PARA_USERNAME)));
		}
		
		/*
		if (StringUtils.isNotBlank(request.getParameter(Constant.PARA_ROLENAME))) {
			list.add(request.getParameter(Constant.PARA_ROLENAME));
		}
		*/
		
		if (list.size() > 0) {
			String[] assignees = new String[list.size()];
			list.toArray(assignees);
			
			facets.getEngine()
				.query()
				.getWorkItems(majorPage, new QueryFilter()
				.setOperators(assignees)
				.setTaskType(TaskType.Major.ordinal()));
			
			wsResp.setPage(majorPage);
		}
		
		return wsResp;
	}
	
	/**
	 * 根据用户名或角色分页查询已办列表
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "history", method=RequestMethod.GET)
	public WsCommonResponse<WorkItem> historyTaskList(HttpServletRequest request) {
		WsCommonResponse<WorkItem> wsResp = new WsCommonResponse<WorkItem>();
		
		int pageSize = 0;
		if (StringUtils.isNotBlank(request.getParameter(Constant.PARA_PAGE_SIZE))) {
			pageSize = Integer.valueOf(request.getParameter(Constant.PARA_PAGE_SIZE));
		}
		
		Page<WorkItem> page = null;
		if (pageSize > 0) {
			page = new Page<WorkItem>(pageSize);
		} else {
			page = new Page<WorkItem>();
		}
		
		int currPage = 1;
		if (pageSize > 0 && StringUtils.isNotBlank(request.getParameter(Constant.PARA_START_IDX))) {
			currPage = Integer.valueOf(request.getParameter(Constant.PARA_START_IDX)) / pageSize + 1;
		}
		
		page.setPageNo(currPage);
		
		List<String> list = new ArrayList<String>();
		if (StringUtils.isNotBlank(request.getParameter(Constant.PARA_USERNAME))) {
			list.add(request.getParameter(Constant.PARA_USERNAME));
			list.addAll(ensureGroup(request.getParameter(Constant.PARA_USERNAME)));
		}
		
		if (list.size() > 0) {
			String[] assignees = new String[list.size()];
			list.toArray(assignees);
			
			facets.getEngine().query().getHistoryWorkItems(page, 
				new QueryFilter().setOperators(assignees));
			
			wsResp.setPage(page);
		}
		
		return wsResp;
	}
	
	/** 查询用户角色 */
	@SuppressWarnings("rawtypes")
	private List<String> ensureGroup(String operator) {
		List<String> groups = new ArrayList<String>();
		
		StringBuilder sql = new StringBuilder();
		sql.append("select t1.rolename ");
		sql.append("  from AC_ROLE t1, AC_OPERATORROLE t2, AC_OPERATOR t3");
		sql.append(" where t2.roleid = t1.roleid");
		sql.append("   and t3.operatorid = t2.operatorid");
		sql.append("   and t3.status = ?");
		sql.append("   and t3.userid = ?");
		
		List roleNames = approvalDao.createSQLQuery(sql.toString(), OPERATOR_STATUS, operator).list();
		if (!CollectionUtils.isEmpty(roleNames)) {
			for (Object obj : roleNames) {
				groups.add(obj.toString());
			}
		}
		
		return groups;
	}
	
	/**
     * 执行流程任务
     * @return
     */
    @SuppressWarnings("rawtypes")
	@ResponseBody
	@RequestMapping(value = "execute")
    public WsCommonResponse execute(HttpServletRequest request) {
    	WsCommonResponse wsResp = new WsCommonResponse();
    	
    	String taskId = request.getParameter(Constant.PARA_TASKID);
    	String operator = request.getParameter(Constant.PARA_OPERATOR);
    	
    	// 封装流程分支条件参数
    	// 由于实际业务采用不同意就结束流程的方式，此处暂不处理分支参数
    	
    	facets.execute(taskId, operator, null);
    	// 判断流程是否执行完成
		HistoryTask task = facets.getEngine().query().getHistTask(taskId);
		Order order = facets.getEngine().query().getOrder(task.getOrderId());
		if (order == null) {
			wsResp.setComplete(true);
		}
		
		/*
		if (order != null) {
			Process process = facets.getEngine().process().getProcessById(order.getProcessId());
			ProcessModel model = process.getModel();
			NodeModel currNode =  model.getNode(task.getTaskName());
			List<EndModel> endLst = currNode.getNextModels(EndModel.class);
			if (endLst.size() > 0) {
				wsResp.setComplete(true);
			}
		} else {
			wsResp.setComplete(true);
		}
		*/
    	
    	wsResp.setMsg("任务审批成功.");
    	
        return wsResp;
    }
    
    /**
     * 驳回（到上一个节点）
     * @return
     */
    @SuppressWarnings("rawtypes")
	@ResponseBody
	@RequestMapping(value = "reject")
    public WsCommonResponse reject(HttpServletRequest request) {
    	WsCommonResponse wsResp = new WsCommonResponse();
    	
    	String taskId = request.getParameter(Constant.PARA_TASKID);
    	String operator = request.getParameter(Constant.PARA_OPERATOR);
    	
    	facets.executeAndJump(taskId, operator, null, null);
    	wsResp.setMsg("任务驳回成功.");
    	
        return wsResp;
    }
    
	/**
	 * 历史任务撤回
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	@ResponseBody
	@RequestMapping(value = "undo", method=RequestMethod.GET)
	public WsCommonResponse historyTaskUndo(HttpServletRequest request) {
		WsCommonResponse wsResp = new WsCommonResponse();
		try {
			String taskId = request.getParameter(Constant.PARA_TASKID);
	    	String operator = request.getParameter(Constant.PARA_OPERATOR);
			
			facets.getEngine().task().withdrawTask(taskId, operator);
			wsResp.setMsg("任务撤回成功.");
		} catch(Exception e) {
			wsResp.setMsg(e.getMessage());
			log.error(e.getMessage());
		}
		return wsResp;
	}
}
